/*!
    \file    change log.txt
    \brief   change log for GD32A10x firmware

    \version 2026-01-30, V1.4.0, firmware for GD32A10x
*/

/*
    Copyright (c) 2026, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this 
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice, 
       this list of conditions and the following disclaimer in the documentation 
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors 
       may be used to endorse or promote products derived from this software without 
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/

******************* V1.4.0 2026-01-27 ******************************************************************************************
______________________Common______________________________________________________________________________________________
Fix file:
../Firmware/CMSIS/GD/GD32A10x/Source/system_gd32a10x.c

fix reason: 
Modify the clock source configuration of the internal clock configuration function to the internal clock source

V1.3.0:
RCU_CFG0 |= RCU_PLL_MUL12;
RCU_CFG0 |= RCU_PLL_MUL18;
RCU_CFG0 |= RCU_PLL_MUL27;
RCU_CFG0 |= RCU_PLL_MUL30;

V1.4.0:
RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL12);
RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18);
RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL27);
RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL30);
__________________________________________________________________________________________________________________________

_____________________ ADC ________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_adc.c

fix reason: 
Fixed the MISRA issue.

V1.3.0:
isq &= ~((uint32_t)(ADC_ISQ_ISQN << (5U * ((3 + rank) - inserted_length))));
isq |= ((uint32_t)adc_channel << (5U * ((3 + rank) - inserted_length)));

V1.4.0:
isq &= ~((uint32_t)(ADC_ISQ_ISQN << (5U * ((3U + rank) - inserted_length))));
isq |= ((uint32_t)adc_channel << (5U * ((3U + rank) - inserted_length)));
________________________________________________________________________________________________________________________

______________________BKP_________________________________________________________________________________________________
Fix file:
../Examples/BKP/Backup_data/main.c
../Examples/BKP/Tamper/main.c

fix reason: 
Added software protection: before reading the BKP_DATAx register, the RCU_BDCTL_BKPRST bit must be reset first.

V1.3.0:
none

V1.4.0:
/* confirm RCU_BDCTL_BKPRST bit is reset */
if(RESET != (RCU_BDCTL & RCU_BDCTL_BKPRST)){
    rcu_bkp_reset_disable();
}


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_bkp.c

fix reason: 
Fixed the MISRA 14.7 compliance issues.

V1.3.0:
FlagStatus bkp_flag_get(void)
{
    if(RESET != (BKP_TPCS & BKP_FLAG_TAMPER)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
FlagStatus bkp_flag_get(void)
{
    FlagStatus ret;

    if(RESET != (BKP_TPCS & BKP_FLAG_TAMPER)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}
________________________________________________________________________________________________________________________

______________________CAN_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Include/gd32a10x_can.h

fix reason: 
Fixed the CAN filter register's address bug.

V1.3.0:
#define CAN_F23DATA0(canx)                 REG32((canx) + 0x3F8U)

V1.4.0:
#define CAN_F23DATA0(canx)                 REG32((canx) + 0x2F8U)


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_can.c
../Firmware/GD32A10x_standard_peripheral/Include/gd32a10x_can.h

fix reason: 
Fixed the bug of CAN message cancellation caused by IC design

V1.3.0:
none

void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
{
    if(CAN_MAILBOX0 == mailbox_number) {
        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
        while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) {
        }
    } else if(CAN_MAILBOX1 == mailbox_number) {
        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
        while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)) {
        }
    } else if(CAN_MAILBOX2 == mailbox_number) {
        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
        while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)) {
        }
    } else {
        /* illegal parameters */
    }
}

V1.4.0:
/* CAN maibox empty status mask */
#define CAN_ALL_MAILBOX_EMPTY              ((uint32_t)0x1C000000U)      /*!< CAN maibox empty status mask */

ErrStatus can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
{
    ErrStatus reval = SUCCESS;
    /* timeout for CAN_TSTAT_MSTx bits */
    uint32_t timeout = CAN_TIMEOUT;
    uint32_t reg_value0 = 0U;
    uint32_t reg_value1 = 0U;

    /* get the status of transmit FIFO order */
    reg_value0 = CAN_CTL(can_periph) & CAN_CTL_TFO;

    if(CAN_MAILBOX0 == mailbox_number) {
        reg_value1 = CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS0 | CAN_ALL_MAILBOX_EMPTY);
        if((CAN_CTL_TFO == reg_value0) && (CAN_TSTAT_TMLS0 == reg_value1)){
            reval = ERROR;
        } else {
            CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
            while((CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) && (0U != timeout)) {
                timeout--;
            }
            if(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){
                reval = ERROR;
            }
        }
    } else if(CAN_MAILBOX1 == mailbox_number) {
        reg_value1 = CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS1 | CAN_ALL_MAILBOX_EMPTY);
        if((CAN_CTL_TFO == reg_value0) && (CAN_TSTAT_TMLS1 == reg_value1)){
            reval = ERROR;
        }else{
            CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
            while((CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)) && (0U != timeout)) {
                timeout--;
            }
            if(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)){
                reval = ERROR;
            }
        }
        
    } else if(CAN_MAILBOX2 == mailbox_number) {
        reg_value1 = CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS2 | CAN_ALL_MAILBOX_EMPTY);
        if((CAN_CTL_TFO == reg_value0) && (CAN_TSTAT_TMLS2 == reg_value1)){
            reval = ERROR;
        }else{
            CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
            while((CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)) && (0U != timeout)) {
                timeout--;
            }
            if(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)){
                reval = ERROR;
            }
        }
    } else {
        /* illegal parameters */
    }
    return reval;
}


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_can.c

fix reason: 
Fixed the MISRA 14.7 compliance issues.

V1.3.0:
ErrStatus can_fd_init(uint32_t can_periph, can_fdframe_struct *can_fdframe_init)
{
    uint32_t timeout = CAN_TIMEOUT;
    uint32_t tempreg = 0U;

    /* check null pointer */
    if(0 == can_fdframe_init) {
        return ERROR;
    }
    /* disable sleep mode */
    CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
    /* enable initialize mode */
    CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
    /* wait ACK */
    while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
        timeout--;
    }
    /* check initialize working success */
    if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) {
        return ERROR;
    } else {
        /* set the data bit timing register */
        CAN_DBT(can_periph) = (BT_DSJW((uint32_t)can_fdframe_init->data_resync_jump_width) | \
                               BT_DBS1((uint32_t)can_fdframe_init->data_time_segment_1) | \
                               BT_DBS2((uint32_t)can_fdframe_init->data_time_segment_2) | \
                               BT_BAUDPSC(((uint32_t)can_fdframe_init->data_prescaler) - 1U));

        tempreg = can_fdframe_init->esi_mode | can_fdframe_init->iso_bosch;

        /* Protocol exception event detection */
        if(ENABLE == can_fdframe_init->excp_event_detect) {
            tempreg &= ~CAN_FDCTL_PRED;
        } else {
            tempreg |= CAN_FDCTL_PRED;
        }

        /* Transmitter delay compensation mode */
        if(ENABLE == can_fdframe_init->delay_compensation) {
            tempreg |= CAN_FDCTL_TDCEN;
            /* p_delay_compensation pointer should be config when TDC mode is enabled */
            if(0 != can_fdframe_init->p_delay_compensation) {
                tempreg |= (can_fdframe_init->p_delay_compensation->tdc_mode & CAN_FDCTL_TDCMOD);
                CAN_FDTDC(can_periph) = (FDTDC_TDCF(can_fdframe_init->p_delay_compensation->tdc_filter) | FDTDC_TDCO(
                                             can_fdframe_init->p_delay_compensation->tdc_offset));
            } else {
                return ERROR;
            }
        } else {
            /* Transmitter delay compensation mode is disabled */
            tempreg &= ~CAN_FDCTL_TDCEN;
        }

        /* FD operation mode */
        if(ENABLE == can_fdframe_init->fd_frame) {
            tempreg |= CAN_FDCTL_FDEN;
        } else {
            tempreg &= ~CAN_FDCTL_FDEN;
        }
        CAN_FDCTL(can_periph) = tempreg;

        /* disable initialize mode */
        CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
        timeout = CAN_TIMEOUT;
        /* wait the ACK */
        while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
            timeout--;
        }
        /* check exit initialize mode */
        if(0U == timeout) {
            return ERROR;
        }
    }

    return SUCCESS;
}

FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
{
    /* get flag and interrupt enable state */
    if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))) {
        return SET;
    } else {
        return RESET;
    }
}

FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
{
    uint32_t ret1 = RESET;
    uint32_t ret2 = RESET;

    /* get the status of interrupt flag */
    if(flag == CAN_INT_FLAG_RFL0) {
        ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0);
    } else if(flag == CAN_INT_FLAG_RFL1) {
        ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1);
    } else if(flag == CAN_INT_FLAG_ERRN) {
        ret1 = can_error_get(can_periph);
    } else {
        ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag));
    }
    /* get the status of interrupt enable bit */
    ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag));
    if(ret1 && ret2) {
        return SET;
    } else {
        return RESET;
    }
}

V1.4.0:
ErrStatus can_fd_init(uint32_t can_periph, can_fdframe_struct *can_fdframe_init)
{
    uint32_t timeout = CAN_TIMEOUT;
    uint32_t tempreg = 0U;
    ErrStatus reval = SUCCESS;

    /* check null pointer */
    if(0 == can_fdframe_init) {
        reval = ERROR;
    }
    /* disable sleep mode */
    CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
    /* enable initialize mode */
    CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
    /* wait ACK */
    while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
        timeout--;
    }
    /* check initialize working success */
    if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) {
        reval = ERROR;
    } else {
        /* set the data bit timing register */
        CAN_DBT(can_periph) = (BT_DSJW((uint32_t)can_fdframe_init->data_resync_jump_width) | \
                               BT_DBS1((uint32_t)can_fdframe_init->data_time_segment_1) | \
                               BT_DBS2((uint32_t)can_fdframe_init->data_time_segment_2) | \
                               BT_BAUDPSC(((uint32_t)can_fdframe_init->data_prescaler) - 1U));

        tempreg = can_fdframe_init->esi_mode | can_fdframe_init->iso_bosch;

        /* Protocol exception event detection */
        if(ENABLE == can_fdframe_init->excp_event_detect) {
            tempreg &= ~CAN_FDCTL_PRED;
        } else {
            tempreg |= CAN_FDCTL_PRED;
        }

        /* Transmitter delay compensation mode */
        if(ENABLE == can_fdframe_init->delay_compensation) {
            tempreg |= CAN_FDCTL_TDCEN;
            /* p_delay_compensation pointer should be config when TDC mode is enabled */
            if(0 != can_fdframe_init->p_delay_compensation) {
                tempreg |= (can_fdframe_init->p_delay_compensation->tdc_mode & CAN_FDCTL_TDCMOD);
                CAN_FDTDC(can_periph) = (FDTDC_TDCF(can_fdframe_init->p_delay_compensation->tdc_filter) | FDTDC_TDCO(
                                             can_fdframe_init->p_delay_compensation->tdc_offset));
            } else {
                reval = ERROR;
            }
        } else {
            /* Transmitter delay compensation mode is disabled */
            tempreg &= ~CAN_FDCTL_TDCEN;
        }

        /* FD operation mode */
        if(ENABLE == can_fdframe_init->fd_frame) {
            tempreg |= CAN_FDCTL_FDEN;
        } else {
            tempreg &= ~CAN_FDCTL_FDEN;
        }
        CAN_FDCTL(can_periph) = tempreg;

        /* disable initialize mode */
        CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
        timeout = CAN_TIMEOUT;
        /* wait the ACK */
        while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
            timeout--;
        }
        /* check exit initialize mode */
        if(0U == timeout) {
            reval = ERROR;
        }
    }

    return reval;
}

FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
{
    FlagStatus retval;
    /* get flag and interrupt enable state */
    if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))) {
        retval = SET;
    } else {
        retval = RESET;
    }
    return retval;
}

FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
{
    FlagStatus retval;
    uint32_t ret1 = RESET;
    uint32_t ret2 = RESET;

    /* get the status of interrupt flag */
    if(flag == CAN_INT_FLAG_RFL0) {
        ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0);
    } else if(flag == CAN_INT_FLAG_RFL1) {
        ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1);
    } else if(flag == CAN_INT_FLAG_ERRN) {
        ret1 = can_error_get(can_periph);
    } else {
        ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag));
    }
    /* get the status of interrupt enable bit */
    ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag));
    if(ret1 && ret2) {
        retval = SET;
    } else {
        retval = RESET;
    }
    return retval;
}
__________________________________________________________________________________________________________________________

______________________CRC_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Include/gd32a10x_crc.h
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_crc.c

fix reason: 
Fixed MISRA 17.4 issue.

V1.3.0:
uint32_t crc_block_data_calculate(const uint32_t *array, uint32_t size);

uint32_t crc_block_data_calculate(const uint32_t *array, uint32_t size)
{
    uint32_t index;
    for(index = 0U; index < size; index++){
        CRC_DATA = *(array+index);
    }
    return (CRC_DATA);
}

V1.4.0:
uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size);

uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size)
{
    uint32_t index;
    for(index = 0U; index < size; index++){
        CRC_DATA = array[index];
    }
    return (CRC_DATA);
}

__________________________________________________________________________________________________________________

______________________CTC_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_ctc.c

fix reason: 
Fixed MISRA 17.4 issue.

V1.3.0:
FlagStatus ctc_counter_direction_read(void)
{
    if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus ctc_interrupt_flag_get(uint32_t interrupt)
{
    uint32_t intflag = 0U, intenable = 0U;
    
    /* check whether the interrupt is enabled */
    if(RESET != (interrupt & CTC_FLAG_MASK)){
        intenable = CTC_CTL0 & CTC_CTL0_ERRIE;
    }else{
        intenable = CTC_CTL0 & interrupt;
    }
    
    /* get interrupt flag status */
    intflag = CTC_STAT & interrupt;

    if(intflag && intenable){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus ctc_flag_get(uint32_t flag)
{
    if(RESET != (CTC_STAT & flag)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
FlagStatus ctc_counter_direction_read(void)
{
    FlagStatus ret;

    if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}

FlagStatus ctc_interrupt_flag_get(uint32_t interrupt)
{
    uint32_t intflag = 0U, intenable = 0U;
    FlagStatus ret;

    /* check whether the interrupt is enabled */
    if(RESET != (interrupt & CTC_FLAG_MASK)){
        intenable = CTC_CTL0 & CTC_CTL0_ERRIE;
    }else{
        intenable = CTC_CTL0 & interrupt;
    }
    
    /* get interrupt flag status */
    intflag = CTC_STAT & interrupt;

    if(intflag && intenable){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}

FlagStatus ctc_flag_get(uint32_t flag)
{
    FlagStatus ret;

    if(RESET != (CTC_STAT & flag)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}
__________________________________________________________________________________________________________________________

______________________DAC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DBG_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DMA_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_dma.c

fix reason: 
Fixed MISRA 17.4 issue.

V1.3.0:
FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
{
    uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
    
    switch(flag){
        case DMA_INT_FLAG_FTF:
            /* check whether the full transfer finish interrupt flag is set and enabled */
            interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
            interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
            break;
        case DMA_INT_FLAG_HTF:
            /* check whether the half transfer finish interrupt flag is set and enabled */
            interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
            interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
            break;
        case DMA_INT_FLAG_ERR:
            /* check whether the error interrupt flag is set and enabled */
            interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
            interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE;
            break;
        default:
            DMA_WRONG_HANDLE
        }
    
    /* when the interrupt flag is set and enabled, return SET */
    if((0U != interrupt_flag) && (0U != interrupt_enable)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
{
    uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
    FlagStatus status = RESET;
    
    switch(flag){
        case DMA_INT_FLAG_FTF:
            /* check whether the full transfer finish interrupt flag is set and enabled */
            interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
            interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
            break;
        case DMA_INT_FLAG_HTF:
            /* check whether the half transfer finish interrupt flag is set and enabled */
            interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
            interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
            break;
        case DMA_INT_FLAG_ERR:
            /* check whether the error interrupt flag is set and enabled */
            interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
            interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE;
            break;
        default:
            DMA_WRONG_HANDLE
        }
    
    /* when the interrupt flag is set and enabled, return SET */
    if((0U != interrupt_flag) && (0U != interrupt_enable)){
        status = SET;
    }else{
        status = RESET;
    }
    return status;
}
__________________________________________________________________________________________________________________________

______________________EXMC________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________EXTI________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_misc.c

fix reason: 
Added handling for cases where the function parameter nvic_irq is less than 0.

V1.3.0:
void nvic_irq_enable(IRQn_Type nvic_irq,
                     uint8_t nvic_irq_pre_priority,
                     uint8_t nvic_irq_sub_priority)
{
    uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;

    /* use the priority group value to get the temp_pre and the temp_sub */
    switch((SCB->AIRCR) & (uint32_t)0x700U) {
    case NVIC_PRIGROUP_PRE0_SUB4:
        temp_pre = 0U;
        temp_sub = 0x4U;
        break;
    case NVIC_PRIGROUP_PRE1_SUB3:
        temp_pre = 1U;
        temp_sub = 0x3U;
        break;
    case NVIC_PRIGROUP_PRE2_SUB2:
        temp_pre = 2U;
        temp_sub = 0x2U;
        break;
    case NVIC_PRIGROUP_PRE3_SUB1:
        temp_pre = 3U;
        temp_sub = 0x1U;
        break;
    case NVIC_PRIGROUP_PRE4_SUB0:
        temp_pre = 4U;
        temp_sub = 0x0U;
        break;
    default:
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
        temp_pre = 2U;
        temp_sub = 0x2U;
        break;
    }

    /* get the temp_priority to fill the NVIC->IP register */
    temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
    temp_priority |= nvic_irq_sub_priority & (0x0FU >> (0x4U - temp_sub));
    temp_priority = temp_priority << 0x04U;
    NVIC->IP[nvic_irq] = (uint8_t)temp_priority;

    /* enable the selected IRQ */
    NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
}

V1.4.0:
void nvic_irq_enable(IRQn_Type nvic_irq,
                     uint8_t nvic_irq_pre_priority,
                     uint8_t nvic_irq_sub_priority)
{
    uint32_t nvic_prigroup, nvic_priority;

    /* check current priority group */
    switch(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) {
    case NVIC_PRIGROUP_PRE0_SUB4:
    case NVIC_PRIGROUP_PRE1_SUB3:
    case NVIC_PRIGROUP_PRE2_SUB2:
    case NVIC_PRIGROUP_PRE3_SUB1:
    case NVIC_PRIGROUP_PRE4_SUB0:
        break;
    default:
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
        break;
    }

    /* get the priority group value */
    nvic_prigroup = NVIC_GetPriorityGrouping();

    /* encoding the pre-emption, subpriority priority */
    nvic_priority = NVIC_EncodePriority(nvic_prigroup, (uint32_t)nvic_irq_pre_priority, (uint32_t)nvic_irq_sub_priority);
    /* set priority */
    NVIC_SetPriority(nvic_irq, nvic_priority);

    /* enable the selected IRQ */
    NVIC_EnableIRQ(nvic_irq);
}


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_misc.c

fix reason: 
Fixed the MISRA 12.7 compliance issue.

V1.3.0:
NVIC->ICER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);

V1.4.0:
NVIC->ICER[(uint32_t)nvic_irq >> 0x05U] = (uint32_t)0x01U << ((uint32_t)nvic_irq & (uint8_t)0x1FU);


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_exti.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus exti_flag_get(exti_line_enum linex)
{
    if(RESET != (EXTI_PD & (uint32_t)linex)) {
        return SET;
    } else {
        return RESET;
    }
}

FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
{
    if(RESET != (EXTI_PD & (uint32_t)linex)) {
        return SET;
    } else {
        return RESET;
    }
}

V1.4.0:
FlagStatus exti_flag_get(exti_line_enum linex)
{
    FlagStatus ret;

    if(RESET != (EXTI_PD & (uint32_t)linex)) {
        ret = SET;
    } else {
        ret = RESET;
    }
    return ret;
}

FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
{
    FlagStatus ret;

    if(RESET != (EXTI_PD & (uint32_t)linex)) {
        ret = SET;
    } else {
        ret = RESET;
    }
    return ret;
}
__________________________________________________________________________________________________________________________

______________________FMC_________________________________________________________________________________________________
Fix file:
/GD32A10x_Firmware_Library/Examples/FMC/Erase_Program/main.c
/GD32A10x_Firmware_Library/Examples/FMC/Write_Protection/main.c

fix reason: 
Before performing flash operations, the exception flags must be cleared first.

V1.3.0:
none

V1.4.0:
/* clear all pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGAERR | FMC_FLAG_PGERR);


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_fmc.c

fix reason: 
Fixed the MISRA 10.3 and 14.7 compliance issues.

V1.3.0:
temp = ((uint8_t)((uint8_t)((uint8_t)(ob_fwdgt) | ob_deepsleep) | ob_stdby) | (OB_USER_MASK));

FlagStatus fmc_flag_get(uint32_t flag)
{
    FlagStatus status = RESET;

    if(FMC_STAT & flag){
        status = SET;
    }
    /* return the state of corresponding FMC flag */
    return status;
}

FlagStatus fmc_interrupt_flag_get(uint32_t flag)
{
    FlagStatus status = RESET;

    if(FMC_STAT & flag){
        status = SET;
    }
    /* return the state of corresponding FMC flag */
    return status;
}

V1.4.0:
temp = (uint32_t)(((uint32_t)((uint32_t)(ob_fwdgt) | ob_deepsleep) | ob_stdby) | OB_USER_MASK);

FlagStatus fmc_flag_get(uint32_t flag)
{
    FlagStatus status = RESET;

    if(FMC_STAT & flag){
        status = SET;
    }else{
        status = RESET;
    }
    /* return the state of corresponding FMC flag */
    return status;
}

FlagStatus fmc_interrupt_flag_get(uint32_t flag)
{
    FlagStatus status = RESET;

    if(FMC_STAT & flag){
        status = SET;
    }else{
        status = RESET;
    }
    /* return the state of corresponding FMC flag */
    return status;
}
__________________________________________________________________________________________________________________________

______________________FWDGT_______________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_fwdgt.c

fix reason: 
Fixed the FWDGT driver issue: FWDGT must be enabled first, then write to PSC and RLD, and wait until RUD and PUD are cleared.

V1.3.0:
ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status = RESET;

    /* enable write access to FWDGT_PSC */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* wait until the PUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    } while((--timeout > 0U) && ((uint32_t)RESET != flag_status));

    if((uint32_t)RESET != flag_status) {
        return ERROR;
    }

    /* configure FWDGT */
    FWDGT_PSC = (uint32_t)prescaler_value;

    return SUCCESS;
}

ErrStatus fwdgt_reload_value_config(uint16_t reload_value)
{
    uint32_t timeout = FWDGT_RLD_TIMEOUT;
    uint32_t flag_status = RESET;

    /* enable write access to FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* wait until the RUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
    } while((--timeout > 0U) && ((uint32_t)RESET != flag_status));

    if((uint32_t)RESET != flag_status) {
        return ERROR;
    }

    FWDGT_RLD = RLD_RLD(reload_value);

    return SUCCESS;
}

ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status = RESET;

    /* enable write access to FWDGT_PSC,and FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* wait until the PUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    } while((--timeout > 0U) && ((uint32_t)RESET != flag_status));

    if((uint32_t)RESET != flag_status) {
        return ERROR;
    }

    /* configure FWDGT */
    FWDGT_PSC = (uint32_t)prescaler_div;

    timeout = FWDGT_RLD_TIMEOUT;
    /* wait until the RUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
    } while((--timeout > 0U) && ((uint32_t)RESET != flag_status));

    if((uint32_t)RESET != flag_status) {
        return ERROR;
    }

    FWDGT_RLD = RLD_RLD(reload_value);

    /* reload the counter */
    FWDGT_CTL = FWDGT_KEY_RELOAD;

    return SUCCESS;
}

FlagStatus fwdgt_flag_get(uint16_t flag)
{
    if(FWDGT_STAT & flag) {
        return SET;
    }

    return RESET;
}

V1.4.0:
ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status;
    ErrStatus status = SUCCESS;

    /* enable write access to FWDGT_PSC */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* configure FWDGT_PSC */
    FWDGT_PSC = (uint32_t)prescaler_value;

    /* wait until the PUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    } while((--timeout > 0U) && (0U != flag_status));

    if(0U != flag_status) {
        status = ERROR;
    }

    return status;
}

ErrStatus fwdgt_reload_value_config(uint16_t reload_value)
{
    uint32_t timeout = FWDGT_RLD_TIMEOUT;
    uint32_t flag_status;
    ErrStatus status = SUCCESS;

    /* enable write access to FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* configure FWDGT_RLD */
    FWDGT_RLD = RLD_RLD(reload_value);

    /* wait until the RUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
    } while((--timeout > 0U) && (0U != flag_status));

    if(0U != flag_status) {
        status = ERROR;
    }

    return status;
}

ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_value)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status;
    ErrStatus status = SUCCESS;

    /* start the free watchdog timer counter */
    FWDGT_CTL = FWDGT_KEY_ENABLE;

    /* enable write access to FWDGT_PSC,and FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* configure FWDGT_PSC */
    FWDGT_PSC = (uint32_t)prescaler_value;

    /* wait until the PUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    } while((--timeout > 0U) && (0U != flag_status));

    if(0U != flag_status) {
        status = ERROR;
    }

    if(SUCCESS == status) {
        /* configure FWDGT_RLD */
        FWDGT_RLD = RLD_RLD(reload_value);

        /* wait until the RUD flag to be reset */
        timeout = FWDGT_RLD_TIMEOUT;
        do {
            flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
        } while((--timeout > 0U) && (0U != flag_status));

        if(0U != flag_status) {
            status = ERROR;
        }
    }

    if(SUCCESS == status) {
        /* reload the counter */
        FWDGT_CTL = FWDGT_KEY_RELOAD;
    }

    return status;
}

FlagStatus fwdgt_flag_get(uint16_t flag)
{
    FlagStatus flag_status = RESET;

    if(RESET != (FWDGT_STAT & flag)) {
        flag_status = SET;
    }
    return flag_status;
}


Fix file:
../Examples/FWDGT/FWDGT_key/main.c

fix reason: 
After the FWDGT driver modification, fwdgt_config has implemented the fwdgt_enable function; therefore, fwdgt_enable is removed.

V1.3.0:
/* after 1.6 seconds to generate a reset */
fwdgt_enable();

V1.4.0:
none
__________________________________________________________________________________________________________________________

______________________GPIO________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_gpio.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
{
    if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
        return SET; 
    }else{
        return RESET;
    }
}

FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
{
    if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus gpio_compensation_flag_get(void)
{
    if(((uint32_t)RESET) != (AFIO_CPSCTL & AFIO_CPSCTL_CPS_RDY)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
{
    FlagStatus status = RESET;
    if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
        status = SET;
    }else{
        status = RESET;
    }
    return status;
}

FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
{
    FlagStatus status = RESET;
    if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
        status = SET;
    }else{
        status = RESET;
    }
    return status;
}

FlagStatus gpio_compensation_flag_get(void)
{
    FlagStatus status = RESET;
    if(((uint32_t)RESET) != (AFIO_CPSCTL & AFIO_CPSCTL_CPS_RDY)){
        status = SET;
    }else{
        status = RESET;
    }
    return status;
}
__________________________________________________________________________________________________________________________

______________________I2C_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_i2c.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag)
{
    if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
{
    uint32_t intenable = 0U, flagstatus = 0U, bufie;

    /* check BUFIE */
    bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;

    /* get the interrupt enable bit status */
    intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
    /* get the corresponding flag bit status */
    flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));

    if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)){
        if(intenable && bufie){
            intenable = 1U;
        }else{
            intenable = 0U;
        }
    }
    if((0U != flagstatus) && (0U != intenable)){
        return SET;
    }else{
        return RESET; 
    }
}

V1.4.0:
FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag)
{
    FlagStatus status = RESET;
    if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))){
        status = SET;
    }else{
        status = RESET;
    }
    return status;
}

FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
{
    uint32_t intenable = 0U, flagstatus = 0U, bufie;
    FlagStatus status = RESET;
    /* check BUFIE */
    bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;

    /* get the interrupt enable bit status */
    intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
    /* get the corresponding flag bit status */
    flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));

    if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)){
        if(intenable && bufie){
            intenable = 1U;
        }else{
            intenable = 0U;
        }
    }
    if((0U != flagstatus) && (0U != intenable)){
        status = SET;
    }else{
        status = RESET; 
    }
    return status;
}
__________________________________________________________________________________________________________________________

______________________PMU_________________________________________________________________________________________________
Fix file:
../Examples/PMU/Deepsleep_wakeup_RTC/main.c
../Examples/PMU/Deepsleep_wakeup_exti/main.c
../Examples/PMU/Standby_wakeup_RTC/main.c
../Examples/PMU/Standby_wakeup_pin/main.c

fix reason: 
Add frequency switching patch to the PMU example.

V1.3.0:
none

V1.4.0:
/* software delay to prevent the impact of Vcore fluctuations.
   It is strongly recommended to include it to avoid issues caused by self-removal. */
static void _soft_delay_(uint32_t time)
{
    __IO uint32_t i;
    for(i=0; i<time*10; i++){
    }
}

/* The following is to prevent Vcore fluctuations caused by frequency switching. 
    It is strongly recommended to include it to avoid issues caused by self-removal. */
_soft_delay_(0x50);
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV2);
_soft_delay_(0x50);
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV4);
_soft_delay_(0x50);
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV8);
_soft_delay_(0x50);
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV16);
_soft_delay_(0x50);
rcu_system_clock_source_config(RCU_CKSYSSRC_IRC8M);
_soft_delay_(200);
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_pmu.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus pmu_flag_get(uint32_t flag)
{
    if(RESET != (PMU_CS & flag)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
FlagStatus pmu_flag_get(uint32_t flag)
{
    FlagStatus ret;

    if(RESET != (PMU_CS & flag)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}
______________________________________________________________________________________________________________________

______________________RCU_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_rcu.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus rcu_flag_get(rcu_flag_enum flag)
{
    /* get the rcu flag */
    if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag)
{
    /* get the rcu interrupt flag */
    if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0
FlagStatus rcu_flag_get(rcu_flag_enum flag)
{
    FlagStatus rcu_flag = RESET;

    /* get the rcu flag */
    if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){
        rcu_flag = SET;
    }else{
        rcu_flag = RESET;
    }

    return rcu_flag;
}

FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag)
{
    FlagStatus rcu_int_flag = RESET;

    /* get the rcu interrupt flag */
    if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){
        rcu_int_flag = SET;
    }else{
        rcu_int_flag = RESET;
    }

    return rcu_int_flag;
}
__________________________________________________________________________________________________________________________

______________________RTC_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_rtc.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus rtc_flag_get(uint32_t flag)
{
    if(RESET != (RTC_CTL & flag)){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus rtc_interrupt_flag_get(uint32_t flag)
{
    if(RESET != (RTC_CTL & flag)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0
FlagStatus rtc_flag_get(uint32_t flag)
{
    FlagStatus ret;

    if(RESET != (RTC_CTL & flag)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}

FlagStatus rtc_interrupt_flag_get(uint32_t flag)
{
    FlagStatus ret;

    if(RESET != (RTC_CTL & flag)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}
__________________________________________________________________________________________________________________________

______________________SPI_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Include/gd32a10x_spi.h
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_spi.c

fix reason: 
Delete 'spi_quad_io23_output_enable' and 'spi_quad_io23_output_disable' function.

V1.3.0:
#define SPI_QCTL_IO23_DRV               BIT(2)                                  /*!< drive SPI_IO2 and SPI_IO3 enable */

/* enable SPI quad wire mode SPI_IO2 and SPI_IO3 pin output */
void spi_quad_io23_output_enable(uint32_t spi_periph);
/* disable SPI quad wire mode SPI_IO2 and SPI_IO3 pin output */
void spi_quad_io23_output_disable(uint32_t spi_periph);

/*!
    \brief      enable SPI quad wire mode SPI_IO2 and SPI_IO3 pin output
    \param[in]  spi_periph: SPIx(only x=0)
    \param[out] none
    \retval     none
*/
void spi_quad_io23_output_enable(uint32_t spi_periph)
{
    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV;
}

 /*!
    \brief      disable SPI quad wire mode SPI_IO2 and SPI_IO3 pin output
    \param[in]  spi_periph: SPIx(only x=0)
    \param[out] none
    \retval     none
*/
void spi_quad_io23_output_disable(uint32_t spi_periph)
{
    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
}

V1.4.0:
none


Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_spi.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
uint16_t spi_crc_get(uint32_t spi_periph,uint8_t crc)
{
    if(SPI_CRC_TX == crc){
        return ((uint16_t)(SPI_TCRC(spi_periph)));
    }else{
        return ((uint16_t)(SPI_RCRC(spi_periph)));
    }
}

FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt)
{
    uint32_t reg1 = SPI_STAT(spi_periph);
    uint32_t reg2 = SPI_CTL1(spi_periph);

    switch(interrupt){
    /* SPI/I2S transmit buffer empty interrupt */
    case SPI_I2S_INT_FLAG_TBE:
        reg1 = reg1 & SPI_STAT_TBE;
        reg2 = reg2 & SPI_CTL1_TBEIE;
        break;
    /* SPI/I2S receive buffer not empty interrupt */
    case SPI_I2S_INT_FLAG_RBNE:
        reg1 = reg1 & SPI_STAT_RBNE;
        reg2 = reg2 & SPI_CTL1_RBNEIE;
        break;
    /* SPI/I2S overrun interrupt */
    case SPI_I2S_INT_FLAG_RXORERR:
        reg1 = reg1 & SPI_STAT_RXORERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* SPI config error interrupt */
    case SPI_INT_FLAG_CONFERR:
        reg1 = reg1 & SPI_STAT_CONFERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* SPI CRC error interrupt */
    case SPI_INT_FLAG_CRCERR:
        reg1 = reg1 & SPI_STAT_CRCERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* I2S underrun error interrupt */
    case I2S_INT_FLAG_TXURERR:
        reg1 = reg1 & SPI_STAT_TXURERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* SPI/I2S format error interrupt */
    case SPI_I2S_INT_FLAG_FERR:
        reg1 = reg1 & SPI_STAT_FERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    default:
        break;
    }
    /* get SPI/I2S interrupt flag status */
    if((0U != reg1) && (0U != reg2)){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag)
{
    if(RESET != (SPI_STAT(spi_periph) & flag)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
uint16_t spi_crc_get(uint32_t spi_periph,uint8_t crc)
{
    uint16_t crc_value;
    if(SPI_CRC_TX == crc){
        crc_value = ((uint16_t)(SPI_TCRC(spi_periph)));
    }else{
        crc_value = ((uint16_t)(SPI_RCRC(spi_periph)));
    }

    return crc_value;
}

FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt)
{
    FlagStatus status = RESET;
    uint32_t reg1 = SPI_STAT(spi_periph);
    uint32_t reg2 = SPI_CTL1(spi_periph);

    switch(interrupt){
    /* SPI/I2S transmit buffer empty interrupt */
    case SPI_I2S_INT_FLAG_TBE:
        reg1 = reg1 & SPI_STAT_TBE;
        reg2 = reg2 & SPI_CTL1_TBEIE;
        break;
    /* SPI/I2S receive buffer not empty interrupt */
    case SPI_I2S_INT_FLAG_RBNE:
        reg1 = reg1 & SPI_STAT_RBNE;
        reg2 = reg2 & SPI_CTL1_RBNEIE;
        break;
    /* SPI/I2S overrun interrupt */
    case SPI_I2S_INT_FLAG_RXORERR:
        reg1 = reg1 & SPI_STAT_RXORERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* SPI config error interrupt */
    case SPI_INT_FLAG_CONFERR:
        reg1 = reg1 & SPI_STAT_CONFERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* SPI CRC error interrupt */
    case SPI_INT_FLAG_CRCERR:
        reg1 = reg1 & SPI_STAT_CRCERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* I2S underrun error interrupt */
    case I2S_INT_FLAG_TXURERR:
        reg1 = reg1 & SPI_STAT_TXURERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    /* SPI/I2S format error interrupt */
    case SPI_I2S_INT_FLAG_FERR:
        reg1 = reg1 & SPI_STAT_FERR;
        reg2 = reg2 & SPI_CTL1_ERRIE;
        break;
    default:
        break;
    }
    /* get SPI/I2S interrupt flag status */
    if((0U != reg1) && (0U != reg2)){
        status = SET;
    }else{
        status = RESET;
    }

    return status;
}

FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag)
{
    FlagStatus status = RESET;
    if(RESET != (SPI_STAT(spi_periph) & flag)){
        status = SET;
    }else{
        status = RESET;
    }

    return status;
}
__________________________________________________________________________________________________________________________

______________________TIMER_______________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_timer.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt)
{
    uint32_t val;
    val = (TIMER_DMAINTEN(timer_periph) & interrupt);
    if((RESET != (TIMER_INTF(timer_periph) & interrupt)) && (RESET != val)){
        return SET;
    }else{
        return RESET;
    }
}

FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag)
{
    if(RESET != (TIMER_INTF(timer_periph) & flag)){
        return SET;
    }else{
        return RESET;
    }
}

V1.4.0:
FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt)
{
    uint32_t val;
    FlagStatus ret;
    val = (TIMER_DMAINTEN(timer_periph) & interrupt);
    if((RESET != (TIMER_INTF(timer_periph) & interrupt)) && (RESET != val)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}

FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag)
{
    FlagStatus ret;
    if(RESET != (TIMER_INTF(timer_periph) & flag)){
        ret = SET;
    }else{
        ret = RESET;
    }
    return ret;
}
__________________________________________________________________________________________________________________________

______________________USART_______________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_usart.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
{
    if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))) {
        return SET;
    } else {
        return RESET;
    }
}

FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
{
    uint32_t intenable = 0U, flagstatus = 0U;
    /* get the interrupt enable bit status */
    intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
    /* get the corresponding flag bit status */
    flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));

    if((0U != flagstatus) && (0U != intenable)) {
        return SET;
    } else {
        return RESET;
    }
}

V1.4.0:
FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
{
    FlagStatus ret;

    if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))) {
        ret = SET;
    } else {
        ret = RESET;
    }
    return ret;
}

FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
{
    uint32_t intenable = 0U, flagstatus = 0U;
    FlagStatus ret;
    /* get the interrupt enable bit status */
    intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
    /* get the corresponding flag bit status */
    flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));

    if((0U != flagstatus) && (0U != intenable)) {
        ret = SET;
    } else {
        ret = RESET;
    }
    return ret;
}
__________________________________________________________________________________________________________________________

______________________USBFS_______________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________WWDGT_______________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_wwdgt.c

fix reason: 
Fixed the MISRA 14.7 compliance issue.

V1.3.0:
FlagStatus wwdgt_flag_get(void)
{
    if(RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)) {
        return SET;
    }

    return RESET;
}

V1.4.0
FlagStatus wwdgt_flag_get(void)
{
    FlagStatus flag_status = RESET;

    if(RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)) {
        flag_status = SET;
    }

    return flag_status;
}
__________________________________________________________________________________________________________________________


******************* V1.3.0 2025-08-07 ******************************************************************************************
______________________Common______________________________________________________________________________________________
Fix file:
..\Firmware\CMSIS\GD\GD32A10x\Source\system_gd32a10x.c

fix reason: 
Adjust the position of the function to avoid the software delay issue during frequency switching

V1.2.0:
/*!
    \brief      setup the micro controller system, initialize the system
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SystemInit (void)
{
  /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
    /* reset the RCU clock configuration to the default reset state */
    /* Set IRC8MEN bit */
    RCU_CTL |= RCU_CTL_IRC8MEN;
    while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
    }
    if(((RCU_CFG0 & RCU_CFG0_SCSS) == RCU_SCSS_PLL)){
        RCU_MODIFY_4(0x50);
    }
    _soft_delay_(200);

    RCU_CFG0 &= ~RCU_CFG0_SCS;

    /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
    RCU_CTL &= ~(RCU_CTL_PLLEN |RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
    /* disable all interrupts */
    RCU_INT = 0x00ff0000U;

    /* Reset CFG0 and CFG1 registers */
    RCU_CFG0 = 0x00000000U;
    RCU_CFG1 = 0x00000000U;

    /* reset HXTALBPS bit */
    RCU_CTL &= ~(RCU_CTL_HXTALBPS);

    /* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
    system_clock_config();

#ifdef VECT_TAB_SRAM
    nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET);
#else
    nvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET);
#endif
}

V1.3.0:
/*!
    \brief      setup the micro controller system, initialize the system
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SystemInit (void)
{
  /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
    /* reset the RCU clock configuration to the default reset state */
    /* Set IRC8MEN bit */
    RCU_CTL |= RCU_CTL_IRC8MEN;
    while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
    }
    if(((RCU_CFG0 & RCU_CFG0_SCSS) == RCU_SCSS_PLL)){
        RCU_MODIFY_4(0x50);
    }

    RCU_CFG0 &= ~RCU_CFG0_SCS;
    _soft_delay_(200);

    /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
    RCU_CTL &= ~(RCU_CTL_PLLEN |RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
    /* disable all interrupts */
    RCU_INT = 0x00ff0000U;

    /* Reset CFG0 and CFG1 registers */
    RCU_CFG0 = 0x00000000U;
    RCU_CFG1 = 0x00000000U;

    /* reset HXTALBPS bit */
    RCU_CTL &= ~(RCU_CTL_HXTALBPS);

    /* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
    system_clock_config();

#ifdef VECT_TAB_SRAM
    nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET);
#else
    nvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET);
#endif
}
__________________________________________________________________________________________________________________________

_____________________ ADC ________________________________________________________________________________________________


________________________________________________________________________________________________________________________

______________________BKP_________________________________________________________________________________________________


________________________________________________________________________________________________________________________

______________________CAN_________________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_standard_peripheral/Source/gd32a10x_can.c

fix reason: 
When the number of bytes sent by CAN exceeds 8, the frame sent by CAN to the bus will have a problem. Add a limit to the 
code, set to 8 when the number of bytes exceeds 8

V1.2.0:
/*!
    \brief       transmit CAN message
    \param[in]  can_periph
      \arg        CANx(x=0,1)
    \param[in]  transmit_message: struct for CAN transmit message
      \arg        tx_sfid: 0x00000000 - 0x000007FF
      \arg        tx_efid: 0x00000000 - 0x1FFFFFFF
      \arg        tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
      \arg        tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
      \arg        tx_dlen: 0 - 8 (FD mode: 0 - 8, or 12, 16, 20, 24, 32, 48, 64)
      \arg        tx_data[]: 0x00 - 0xFF
    \param[out] none
    \retval     mailbox_number
*/
uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message)
{
    uint8_t mailbox_number = CAN_MAILBOX0;
    uint8_t i = 0U;
    uint8_t hit = 0U;
    uint32_t canfd_en = 0U;
    volatile uint32_t p_temp;
    uint32_t reg_temp = 0U;

    /* select one empty mailbox */
    if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)) {
        mailbox_number = CAN_MAILBOX0;
    } else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)) {
        mailbox_number = CAN_MAILBOX1;
    } else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)) {
        mailbox_number = CAN_MAILBOX2;
    } else {
        mailbox_number = CAN_NOMAILBOX;
    }
    /* return no mailbox empty */
    if(CAN_NOMAILBOX == mailbox_number) {
        return CAN_NOMAILBOX;
    }

    CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
    if(CAN_FF_STANDARD == transmit_message->tx_ff) {
        /* set transmit mailbox standard identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
                                               transmit_message->tx_ft);
    } else {
        /* set transmit mailbox extended identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
                                               transmit_message->tx_ff | \
                                               transmit_message->tx_ft);
    }

    if(CAN_FDF_CLASSIC == transmit_message->fd_flag) {
        /* set the data length */
        CAN_TMP(can_periph, mailbox_number) &= ~(CAN_TMP_DLENC | CAN_TMP_ESI | CAN_TMP_BRS | CAN_TMP_FDF);
        CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
        /* set the data */
        CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
                TMDATA0_DB2(transmit_message->tx_data[2]) | \
                TMDATA0_DB1(transmit_message->tx_data[1]) | \
                TMDATA0_DB0(transmit_message->tx_data[0]);
        CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
                TMDATA1_DB6(transmit_message->tx_data[6]) | \
                TMDATA1_DB5(transmit_message->tx_data[5]) | \
                TMDATA1_DB4(transmit_message->tx_data[4]);
    } else {
        canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
        /* check FD function has been enabled */
        if(canfd_en) {
            if(transmit_message->tx_dlen <= 8U) {
                /* set the data length */
                reg_temp |= transmit_message->tx_dlen;
            } else {
                /* data length greater than 8 */
                for(i = 0U; i < 7U; i++) {
                    if(transmit_message->tx_dlen == g_can_fdlength_table[i]) {
                        hit = 1U;
                        break;
                    }
                }
                /* data length is valid */
                if(1U == hit) {
                    reg_temp |= 9U + i;
                } else {
                    CAN_ERROR_HANDLE("dlen is invalid \r\n");
                }
            }
            reg_temp |= (((uint32_t)transmit_message->fd_brs << 5U) | ((uint32_t)transmit_message->fd_esi << 4U) | ((uint32_t)transmit_message->fd_flag << 7U));
            CAN_TMP(can_periph, mailbox_number) = reg_temp;

            /* set the data */
            i = transmit_message->tx_dlen / 4U;

            /* data length is 5-7 need send 2 word */
            if((1U == i) && (4U != transmit_message->tx_dlen)) {
                i++;
            }
            p_temp = (uint32_t)transmit_message->tx_data;
            if((0U == i)) {
                CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
            } else {
                for(; i > 0U; i--) {
                    CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
                    p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
                }
            }

        } else {
            CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
        }
    }

    /* enable transmission */
    CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;

    return mailbox_number;
}

V1.3.0:
/*!
    \brief       transmit CAN message
    \param[in]  can_periph
      \arg        CANx(x=0,1)
    \param[in]  transmit_message: struct for CAN transmit message
      \arg        tx_sfid: 0x00000000 - 0x000007FF
      \arg        tx_efid: 0x00000000 - 0x1FFFFFFF
      \arg        tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
      \arg        tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
      \arg        tx_dlen: 0 - 8 (FD mode: 0 - 8, or 12, 16, 20, 24, 32, 48, 64)
      \arg        tx_data[]: 0x00 - 0xFF
    \param[out] none
    \retval     mailbox_number
*/
uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message)
{
    uint8_t mailbox_number = CAN_MAILBOX0;
    uint8_t i = 0U;
    uint8_t hit = 0U;
    uint32_t canfd_en = 0U;
    volatile uint32_t p_temp;
    uint32_t reg_temp = 0U;

    /* select one empty mailbox */
    if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)) {
        mailbox_number = CAN_MAILBOX0;
    } else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)) {
        mailbox_number = CAN_MAILBOX1;
    } else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)) {
        mailbox_number = CAN_MAILBOX2;
    } else {
        mailbox_number = CAN_NOMAILBOX;
    }
    /* return no mailbox empty */
    if(CAN_NOMAILBOX == mailbox_number) {
        return CAN_NOMAILBOX;
    }

    CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
    if(CAN_FF_STANDARD == transmit_message->tx_ff) {
        /* set transmit mailbox standard identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
                                               transmit_message->tx_ft);
    } else {
        /* set transmit mailbox extended identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
                                               transmit_message->tx_ff | \
                                               transmit_message->tx_ft);
    }

    if(CAN_FDF_CLASSIC == transmit_message->fd_flag) {
        /* set the data length */
        CAN_TMP(can_periph, mailbox_number) &= ~(CAN_TMP_DLENC | CAN_TMP_ESI | CAN_TMP_BRS | CAN_TMP_FDF);
		/* Classic CAN frame data length does not exceed 8 */
        if (transmit_message->tx_dlen > 8U) {
            transmit_message->tx_dlen = 8U;
        }
        CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
        /* set the data */
        CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
                TMDATA0_DB2(transmit_message->tx_data[2]) | \
                TMDATA0_DB1(transmit_message->tx_data[1]) | \
                TMDATA0_DB0(transmit_message->tx_data[0]);
        CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
                TMDATA1_DB6(transmit_message->tx_data[6]) | \
                TMDATA1_DB5(transmit_message->tx_data[5]) | \
                TMDATA1_DB4(transmit_message->tx_data[4]);
    } else {
        canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
        /* check FD function has been enabled */
        if(canfd_en) {
            if(transmit_message->tx_dlen <= 8U) {
                /* set the data length */
                reg_temp |= transmit_message->tx_dlen;
            } else {
                /* data length greater than 8 */
                for(i = 0U; i < 7U; i++) {
                    if(transmit_message->tx_dlen == g_can_fdlength_table[i]) {
                        hit = 1U;
                        break;
                    }
                }
                /* data length is valid */
                if(1U == hit) {
                    reg_temp |= 9U + i;
                } else {
                    CAN_ERROR_HANDLE("dlen is invalid \r\n");
                }
            }
            reg_temp |= (((uint32_t)transmit_message->fd_brs << 5U) | ((uint32_t)transmit_message->fd_esi << 4U) | ((uint32_t)transmit_message->fd_flag << 7U));
            CAN_TMP(can_periph, mailbox_number) = reg_temp;

            /* set the data */
            i = transmit_message->tx_dlen / 4U;

            /* data length is 5-7 need send 2 word */
            if((1U == i) && (4U != transmit_message->tx_dlen)) {
                i++;
            }
            p_temp = (uint32_t)transmit_message->tx_data;
            if((0U == i)) {
                CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
            } else {
                for(; i > 0U; i--) {
                    CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
                    p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
                }
            }

        } else {
            CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
        }
    }

    /* enable transmission */
    CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;

    return mailbox_number;
}
__________________________________________________________________________________________________________________________

______________________CRC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________

______________________CTC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DAC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DBG_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DMA_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________EXMC________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________EXTI________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________FMC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________FWDGT_______________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________GPIO________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________I2C_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________PMU_________________________________________________________________________________________________


______________________________________________________________________________________________________________________

______________________RCU_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________RTC_________________________________________________________________________________________________
Fix file:
../Examples/RTC/Calendar_demo/main.c

fix reason: 
Before reading BKP_DATAx, the RCU_BDCTL_BKPRST bit must be cleared first; otherwise, it may cause the MCU to crash.

V1.2.0:
/*!
    \brief      different processes depending on the backup data to display calendar on LCD
    \param[in]  none
    \param[out] none
    \retval     none
*/
void rtc_process(void)
{
    uint32_t rtcsrc_flag = 0;

    printf("\r\n This is a RTC demo......" );

    /* get RTC clock entry selection */
    rtcsrc_flag = GET_BITS(RCU_BDCTL, 8, 9);

    if((bkp_data_read(BKP_DATA_0) != BACKUP_DATA) || (0U == rtcsrc_flag)){
        /* backup data register value is not correct or not yet programmed
        or RTC clock source is not configured (when the first time the program
        is executed or data in RCU_BDCTL is lost due to Vbat feeding) */
        printf("\r\n RTC has not been configured yet....");

        /* RTC configuration */
        rtc_configuration();

        printf("\r\n start the RTC configuration....");

        /* adjust time by values entered by the user on the hyper terminal */
        time_adjust();

        bkp_data_write(BKP_DATA_0, BACKUP_DATA);
    }else{
        /* check if the power on/down reset flag is set */
        if(rcu_flag_get(RCU_FLAG_PORRST) != RESET){
            printf("\r\n\n Power On/Down Reset occurred....");
        }else if(rcu_flag_get(RCU_FLAG_SWRST) != RESET){
            /* check if the pin reset flag is set */
            printf("\r\n\n External Reset occurred....");
        }

        /* allow access to BKP domain */
        rcu_periph_clock_enable(RCU_PMU);
        pmu_backup_write_enable();
    
        printf("\r\n No need to configure RTC....");
        /* wait for RTC registers synchronization */
        rtc_register_sync_wait();
        rtc_lwoff_wait();
        /* enable the RTC second and alarm interrupt*/
        rtc_interrupt_enable(RTC_INT_SECOND);
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
    }
}
V1.3.0:
/*!
    \brief      different processes depending on the backup data to display calendar on LCD
    \param[in]  none
    \param[out] none
    \retval     none
*/
void rtc_process(void)
{
    uint32_t rtcsrc_flag = 0;

    printf("\r\n This is a RTC demo......" );

    /* enable PMU and BKPI clocks */
    rcu_periph_clock_enable(RCU_BKPI);
    rcu_periph_clock_enable(RCU_PMU);
    /* allow access to BKP domain */
    pmu_backup_write_enable();
    if(RESET != (RCU_BDCTL & RCU_BDCTL_BKPRST)) {
        rcu_bkp_reset_disable();
    }

    /* get RTC clock entry selection */
    rtcsrc_flag = GET_BITS(RCU_BDCTL, 8, 9);

    if((bkp_data_read(BKP_DATA_0) != BACKUP_DATA) || (0U == rtcsrc_flag)){
        /* backup data register value is not correct or not yet programmed
        or RTC clock source is not configured (when the first time the program
        is executed or data in RCU_BDCTL is lost due to Vbat feeding) */
        printf("\r\n RTC has not been configured yet....");

        /* RTC configuration */
        rtc_configuration();

        printf("\r\n start the RTC configuration....");

        /* adjust time by values entered by the user on the hyper terminal */
        time_adjust();

        bkp_data_write(BKP_DATA_0, BACKUP_DATA);
    }else{
        /* check if the power on/down reset flag is set */
        if(rcu_flag_get(RCU_FLAG_PORRST) != RESET){
            printf("\r\n\n Power On/Down Reset occurred....");
        }else if(rcu_flag_get(RCU_FLAG_SWRST) != RESET){
            /* check if the pin reset flag is set */
            printf("\r\n\n External Reset occurred....");
        }

        /* allow access to BKP domain */
        rcu_periph_clock_enable(RCU_PMU);
        pmu_backup_write_enable();
    
        printf("\r\n No need to configure RTC....");
        /* wait for RTC registers synchronization */
        rtc_register_sync_wait();
        rtc_lwoff_wait();
        /* enable the RTC second and alarm interrupt*/
        rtc_interrupt_enable(RTC_INT_SECOND);
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
    }
}
__________________________________________________________________________________________________________________________

______________________SPI_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________TIMER_______________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________USART_______________________________________________________________________________________________
Fix file:
../Examples/USART/Half_duplex_transmitter&receiver/main.c
../Examples/USART/Half_duplex_transmitter&receiver/readme.txt

fix reason: 
In the USART half-duplex communication example, modify the TX pin to open-drain output

V1.2.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);

    /* enable USART and GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_USART1);

    /* configure USART0 Tx as alternate function push-pull */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    /* configure USART1 Tx as alternate function push-pull */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);

    /* USART0 and USART1 baudrate configuration */
    usart_baudrate_set(USART0, 115200);
    usart_baudrate_set(USART1, 115200);

    /* enable USART0 half duplex mode*/
    usart_halfduplex_enable(USART0);
    /* enable USART1 half duplex mode*/
    usart_halfduplex_enable(USART1);

    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);

    /* enable USART */
    usart_enable(USART0);
    usart_enable(USART1);

    /* clear the USART1 data register */
    usart_data_receive(USART1);
    /* USART0 transmit and USART1 receive */
    while(transfersize0--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART0, transmitter_buffer0[txcount0++]);

        while(RESET == usart_flag_get(USART1, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer1 */
        receiver_buffer1[rxcount0++] = usart_data_receive(USART1);
    }
    /* clear the USART0 data register */
    usart_data_receive(USART0);
    /* USART1 transmit and USART0 receive */
    while(transfersize1--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART1, transmitter_buffer1[txcount1++]);

        while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer0 */
        receiver_buffer0[rxcount1++] = usart_data_receive(USART0);
    }

    /* compare the received data with the send ones */
    state1 = memory_compare(transmitter_buffer0, receiver_buffer1, TRANSMIT_SIZE0);
    state2 = memory_compare(transmitter_buffer1, receiver_buffer0, TRANSMIT_SIZE1);
    if(SUCCESS == state1) {
        /* if the data transmitted from USART0 and received by USART1 are the same */
        gd_eval_led_on(LED2);
    } else {
        /* if the data transmitted from USART0 and received by USART1 are not the same */
        gd_eval_led_off(LED2);
    }
    if(SUCCESS == state2) {
        /* if the data transmitted from USART1 and received by USART0 are the same */
        gd_eval_led_on(LED3);
    } else {
        /* if the data transmitted from USART1 and received by USART0 are not the same */
        gd_eval_led_off(LED3);
    }
    while(1) {
    }
}

V1.3.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);

    /* enable USART and GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_USART1);

    /* configure USART0 Tx as alternate function open-drain */
    gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    /* configure USART1 Tx as alternate function open-drain */
    gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_2);

    /* USART0 and USART1 baudrate configuration */
    usart_baudrate_set(USART0, 115200);
    usart_baudrate_set(USART1, 115200);

    /* enable USART0 half duplex mode*/
    usart_halfduplex_enable(USART0);
    /* enable USART1 half duplex mode*/
    usart_halfduplex_enable(USART1);

    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);

    /* enable USART */
    usart_enable(USART0);
    usart_enable(USART1);

    /* clear the USART1 data register */
    usart_data_receive(USART1);
    /* USART0 transmit and USART1 receive */
    while(transfersize0--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART0, transmitter_buffer0[txcount0++]);

        while(RESET == usart_flag_get(USART1, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer1 */
        receiver_buffer1[rxcount0++] = usart_data_receive(USART1);
    }
    /* clear the USART0 data register */
    usart_data_receive(USART0);
    /* USART1 transmit and USART0 receive */
    while(transfersize1--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART1, transmitter_buffer1[txcount1++]);

        while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer0 */
        receiver_buffer0[rxcount1++] = usart_data_receive(USART0);
    }

    /* compare the received data with the send ones */
    state1 = memory_compare(transmitter_buffer0, receiver_buffer1, TRANSMIT_SIZE0);
    state2 = memory_compare(transmitter_buffer1, receiver_buffer0, TRANSMIT_SIZE1);
    if(SUCCESS == state1) {
        /* if the data transmitted from USART0 and received by USART1 are the same */
        gd_eval_led_on(LED2);
    } else {
        /* if the data transmitted from USART0 and received by USART1 are not the same */
        gd_eval_led_off(LED2);
    }
    if(SUCCESS == state2) {
        /* if the data transmitted from USART1 and received by USART0 are the same */
        gd_eval_led_on(LED3);
    } else {
        /* if the data transmitted from USART1 and received by USART0 are not the same */
        gd_eval_led_off(LED3);
    }
    while(1) {
    }
}
__________________________________________________________________________________________________________________________

______________________USBFS_______________________________________________________________________________________________
Fix file:
../Firmware/GD32A10x_usbfs_library/driver/Source/drv_usb_dev.c

fix reason: 
Fix the issue where the enum_speed parameter may cause an array out-of-bounds error.
Shift the value of enum_speed after obtaining the ES bit field.

V1.2.0:
/*!
    \brief      active the USB endpoint0 transaction
    \param[in]  udev: pointer to USB device
    \param[in]  transc: the USB endpoint0 transaction
    \param[out] none
    \retval     operation status
*/
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc)
{
    __IO uint32_t *reg_addr = NULL;

    uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES;

    /* get the endpoint number */
    uint8_t ep_num = transc->ep_addr.num;

    if(ep_num) {
        /* not endpoint 0 */
        return USB_FAIL;
    }

    if(transc->ep_addr.dir) {
        reg_addr = &udev->regs.er_in[0]->DIEPCTL;
    } else {
        reg_addr = &udev->regs.er_out[0]->DOEPCTL;
    }

    /* endpoint 0 is activated after USB clock is enabled */
    *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);

    /* set endpoint 0 maximum packet length */
    *reg_addr |= EP0_MAXLEN[enum_speed];

    /* activate endpoint */
    *reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;

    return USB_OK;
}

/*!
    \brief      active the USB transaction
    \param[in]  udev: pointer to USB device
    \param[in]  transc: the USB transaction
    \param[out] none
    \retval     status
*/
usb_status usb_transc_active(usb_core_driver *udev, usb_transc *transc)
{
    __IO uint32_t *reg_addr = NULL;
    uint32_t epinten = 0U;
    uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES;

    /* get the endpoint number */
    uint8_t ep_num = transc->ep_addr.num;

    /* enable endpoint interrupt number */
    if(transc->ep_addr.dir) {
        reg_addr = &udev->regs.er_in[ep_num]->DIEPCTL;

        epinten = 1U << ep_num;
    } else {
        reg_addr = &udev->regs.er_out[ep_num]->DOEPCTL;

        epinten = 1U << (16U + ep_num);
    }

    /* if the endpoint is not active, need change the endpoint control register */
    if(!(*reg_addr & DEPCTL_EPACT)) {
        *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);

        /* set endpoint maximum packet length */
        if(0U == ep_num) {
            *reg_addr |= EP0_MAXLEN[enum_speed];
        } else {
            *reg_addr |= transc->max_len;
        }

        /* activate endpoint */
        *reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;
    }

    /* enable the interrupts for this endpoint */
    udev->regs.dr->DAEPINTEN |= epinten;

    return USB_OK;
}

V1.3.0:
/*!
    \brief      active the USB endpoint0 transaction
    \param[in]  udev: pointer to USB device
    \param[in]  transc: the USB endpoint0 transaction
    \param[out] none
    \retval     operation status
*/
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc)
{
    __IO uint32_t *reg_addr = NULL;

    uint32_t enum_speed = ((udev->regs.dr->DSTAT & DSTAT_ES) >> 1);

    /* get the endpoint number */
    uint8_t ep_num = transc->ep_addr.num;

    if(ep_num) {
        /* not endpoint 0 */
        return USB_FAIL;
    }

    if(transc->ep_addr.dir) {
        reg_addr = &udev->regs.er_in[0]->DIEPCTL;
    } else {
        reg_addr = &udev->regs.er_out[0]->DOEPCTL;
    }

    /* endpoint 0 is activated after USB clock is enabled */
    *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);

    /* set endpoint 0 maximum packet length */
    *reg_addr |= EP0_MAXLEN[enum_speed];

    /* activate endpoint */
    *reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;

    return USB_OK;
}

/*!
    \brief      active the USB transaction
    \param[in]  udev: pointer to USB device
    \param[in]  transc: the USB transaction
    \param[out] none
    \retval     status
*/
usb_status usb_transc_active(usb_core_driver *udev, usb_transc *transc)
{
    __IO uint32_t *reg_addr = NULL;
    uint32_t epinten = 0U;
    uint32_t enum_speed = ((udev->regs.dr->DSTAT & DSTAT_ES) >> 1);

    /* get the endpoint number */
    uint8_t ep_num = transc->ep_addr.num;

    /* enable endpoint interrupt number */
    if(transc->ep_addr.dir) {
        reg_addr = &udev->regs.er_in[ep_num]->DIEPCTL;

        epinten = 1U << ep_num;
    } else {
        reg_addr = &udev->regs.er_out[ep_num]->DOEPCTL;

        epinten = 1U << (16U + ep_num);
    }

    /* if the endpoint is not active, need change the endpoint control register */
    if(!(*reg_addr & DEPCTL_EPACT)) {
        *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);

        /* set endpoint maximum packet length */
        if(0U == ep_num) {
            *reg_addr |= EP0_MAXLEN[enum_speed];
        } else {
            *reg_addr |= transc->max_len;
        }

        /* activate endpoint */
        *reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;
    }

    /* enable the interrupts for this endpoint */
    udev->regs.dr->DAEPINTEN |= epinten;

    return USB_OK;
}
__________________________________________________________________________________________________________________________

______________________WWDGT_______________________________________________________________________________________________


__________________________________________________________________________________________________________________________

